package com.changgou.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.changgou.entity.Result;
import com.changgou.goods.feign.SkuFeign;
import com.changgou.goods.feign.SpuFeign;
import com.changgou.goods.pojo.Sku;
import com.changgou.goods.pojo.Spu;
import com.changgou.order.config.TokenDecode;
import com.changgou.order.pojo.CartItem;
import com.changgou.order.service.CartService;
import com.changgou.order.utils.CookieUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Min;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;


@Service
public class CartServiceImpl implements CartService {

    private static final String CART="Cart_";

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SkuFeign skuFeign;

    @Autowired
    private SpuFeign spuFeign;


    @Autowired
    private TokenDecode tokenDecode;
    /**
     * 添加到购物车:
     * 已经登录
     * @param skuId
     * @param num
     */
    @Override
    public void add(String skuId, Integer num, String userName) throws UnsupportedEncodingException {
        if (StringUtils.isEmpty(userName)){
            add(skuId,num);
            return;
        }
        //获取用户名
        Result<Sku> skuResult = skuFeign.findById(skuId);
        if (!skuResult.isFlag())throw new RuntimeException("查无此商品!");
        Sku sku = skuResult.getData();
        //通过用户名、（品牌）商家获取redis数据
        CartItem cartItem = (CartItem) redisTemplate.boundHashOps(CART + userName).get(skuId);
        //判断购物车是否存在
        if (cartItem==null){
            //购物车不存在新健
            cartItem = sku2CartItem(sku, num);
        }else {
            //如果购物车中已经存在修改相关数据,修改数量
            int newNum = cartItem.getNum() + num;
            changeNum(cartItem,newNum);
        }
        //提交到redis
        //redis hash //uesrname ,skuid,
        redisTemplate.boundHashOps(CART+userName).put(skuId,cartItem);
    }

    /**
     * 改变数量
     * @param cartItem
     * @param newNum
     */
    public void changeNum(CartItem cartItem, Integer newNum){
        cartItem.setNum(newNum);
        cartItem.setMoney(newNum*cartItem.getPrice()); //单价*数量
        cartItem.setPayMoney(newNum*cartItem.getPrice()); //实付金额
        cartItem.setWeight(cartItem.getWeight()*newNum); //重量=单个重量*数量
    }

    /**
     * 添加购物车
     * 未登录存在cookie
     * @param skuId
     * @param num
     */
    @Override
    public void add(String skuId, Integer num) throws UnsupportedEncodingException {
        System.out.println("未登录");
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //获取cookie
        HttpServletRequest request = requestAttributes.getRequest();
        Map<String, String> cookies = CookieUtil.readCookie(request,CART+skuId);
        Result<Sku> skuResult = skuFeign.findById(skuId);
        if (!skuResult.isFlag())throw new RuntimeException("查无此商品!");
        Sku sku = skuResult.getData();
        CartItem cartItem;
        if(cookies==null||cookies.isEmpty()){
            //cookie中不存在添加一条
            cartItem = sku2CartItem(sku, num);

        }else {
            //购物车中已经存在,取出并解析
            String cartItemJson = cookies.get(CART+skuId);
            String oneCartJson = URLDecoder.decode(cartItemJson,"utf-8");
            cartItem = JSON.parseObject(oneCartJson,CartItem.class);
            //修改数量
            int newNum = cartItem.getNum() + num;
            changeNum(cartItem,newNum);
        }
        String oneCartJson = JSON.toJSONString(cartItem);
            String cookieJson = URLEncoder.encode(oneCartJson, "utf-8");
            //cookie中储存skuid num，checked，
            CookieUtil.addCookie(response,"192.168.16.172","/",CART+skuId,cookieJson,60*60*24*30,false);
    }

    /**
     * 获取购物车
     * 从cookie中获取
     * @return
     */
    @Override
    public  Map getListFromCookie()  throws UnsupportedEncodingException{
        int totalNum=0;//总记录数
        int totalPrice=0;//总价
        //获取cookie
        Cookie[] cookies = request.getCookies();
        //将购物车信息处理进
        Map<String, List<CartItem>> cart =new HashMap<String, List<CartItem>>();
        if (cookies==null)return cart;
        for (Cookie cookie : cookies) {
            String name = cookie.getName();
            //获取每一条cookie_cart(cart_开头的数据未购物车数据)数据
            if (name.startsWith(CART)){
                String cartJson = URLDecoder.decode(cookie.getValue(), "utf-8");
                CartItem cartItem = JSON.parseObject(cartJson, CartItem.class);
                //添加选中总计和总价
                if (cartItem==null)continue;
                if(cartItem.getChecked()){
                    totalNum+=cartItem.getNum();
                    totalPrice+=cartItem.getPayMoney();
                }
                //添加信息
                addCartItem(cart,cartItem);
            }
        }
        HashMap<String, Object> resl = new HashMap<>();
        resl.put("totalNum",totalNum);
        resl.put("totalPrice",totalPrice);
        resl.put("cart",cart);
        return resl;
    }

    /**
     * 准备返回的购物车中添加数据
     * @param cart
     * @param cartItem
     */
    private void addCartItem(Map<String, List<CartItem>> cart, CartItem cartItem) {
        //获取当前品牌的集合
        List<CartItem> theSameBrandSkus = cart.get(cartItem.getBrandName());
        //判断该品牌是否存在
        if (theSameBrandSkus == null || theSameBrandSkus.isEmpty()) {
            //不存在新建lsit
            theSameBrandSkus = new ArrayList<>();
            theSameBrandSkus.add(cartItem);
            cart.put(cartItem.getBrandName(), theSameBrandSkus);

        } else {
            //品牌已经存在,直接存入同品牌的集合
            theSameBrandSkus.add(cartItem);
        }
    }


    /**
     * 从redis中获取购物车
     * @param userName
     * @return
     */
    @Override
    public  Map getListFromRedis(String userName) throws UnsupportedEncodingException {
        if (StringUtils.isEmpty(userName)){
            return getListFromCookie();
        }
        int totalNum=0;//总记录数
        int totalPrice=0;//总价
        //从redis中获取购物车数
        List<CartItem> cartItems = null;
        try {
            cartItems = redisTemplate.boundHashOps(CART + userName).values();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //用于封装的map
        Map<String, List<CartItem>> cart = new HashMap<String, List<CartItem>>();
        for (CartItem cartItem : cartItems) {
            //添加总计和总价
            if(cartItem.getChecked()){
                totalNum+=cartItem.getNum();
                totalPrice+=cartItem.getPayMoney();
            }
            //添加信息

            addCartItem(cart,cartItem);
        }
        HashMap<String, Object> resl = new HashMap<>();
        resl.put("totalNum",totalNum);
        resl.put("totalPrice",totalPrice);
        resl.put("cart",cart);
        return resl;
    }

    /**
     * 从cookie中删除
     * @param skuId
     */
    @Override
    public void delete(String skuId) {
        CookieUtil.addCookie(response,"192.168.16.172","/",CART+skuId,"",0,false);
    }

    /**
     * 删除购物车
     * @param skuId
     * @param userName
     */
    @Override
    public void delete(String skuId, String userName) {
        if(StringUtils.isEmpty(userName)){
            delete(skuId);
            return;
        }
        redisTemplate.boundHashOps(CART+userName).delete(skuId);
    }

    /**
     * 在登录情况下修改购物车信息
     * num
     * chect
     * @param skuId
     * @param num
     * @param userName
     */
    @Override
    public void updateNum(String skuId, Integer num, String userName) {
        if(StringUtils.isEmpty(userName)){
            updateNum(skuId,num);
            return;
        };
        BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(CART + userName);
        CartItem cartItem = (CartItem) boundHashOperations.get(skuId);
        changeNum(cartItem,num);
        boundHashOperations.put(skuId,cartItem);
    }

    /**
     * 在未登录情况下修改购物车商品数量
     * @param skuId
     * @param num
     */
    @SneakyThrows
    @Override
    public void updateNum(String skuId, Integer num) {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if ((CART+skuId).equals(cookie.getName())){
                String value = cookie.getValue();
                //解码
                String decode = URLDecoder.decode(value, "utf-8");
                CartItem cartItem = JSON.parseObject(decode, CartItem.class);
                //修改
                changeNum(cartItem,num);
                //编码
                String s = JSON.toJSONString(cartItem);
                String encode = URLEncoder.encode(s, "utf-8");
                CookieUtil.addCookie(response,"192.168.16.172","/",cookie.getName(),encode,60*60*24*30,false);
            }
        }
    }

    /**
     * 修改购物车状态
     * @param skuId
     * @param userName
     */
    @Override
    public void updateChecksd(String skuId, String userName) throws UnsupportedEncodingException {
        if(StringUtils.isEmpty(userName)){
            updateChecksd(skuId);
            return;
        }
        BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(CART + userName);
        CartItem cartItem = (CartItem) boundHashOperations.get(skuId);
        cartItem.setChecked(!cartItem.getChecked());
        boundHashOperations.put(skuId,cartItem);
    }
    /**
     * cookie中
     * 修改购物车状态
     * @param skuId
     */
    @Override
    public void updateChecksd(String skuId) throws UnsupportedEncodingException {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if ((CART+skuId).equals(cookie.getName())){
                //解码
                String value = cookie.getValue();
                String decode = URLDecoder.decode(value, "utf-8");
                CartItem cartItem = JSON.parseObject(decode, CartItem.class);
                //修改状态
                cartItem.setChecked(!cartItem.getChecked());
                //编码
                String s = JSON.toJSONString(cartItem);
                String encode = URLEncoder.encode(s, "utf-8");
                CookieUtil.addCookie(response,"192.168.16.172","/",cookie.getName(),encode,60*60*24*30,false);
            }
        }
    }

    /**
     * 修改所有购物车商品状态
     * @param checikStatus
     * @param userName
     */
    @Override
    public void allChecksd(Boolean checikStatus, String userName) throws UnsupportedEncodingException {
        if (StringUtils.isEmpty(userName)){
            allChecksd(checikStatus);
            return;
        }
        BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(CART + userName);
        Map all = boundHashOperations.entries();
        Set set = all.keySet();
        set.forEach(skuId->{
            CartItem one = (CartItem) all.get(skuId);
            one.setChecked(checikStatus);
        });
        boundHashOperations.putAll(all);
    }

    /**
     * 非登录状态
     * 修改所有购物车商品状态
     * @param checikStatus
     */
    @Override
    public void allChecksd(Boolean checikStatus) throws UnsupportedEncodingException {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            //解码
            String value = cookie.getValue();
            String decode = URLDecoder.decode(value, "utf-8");
            CartItem cartItem = JSON.parseObject(decode, CartItem.class);
            //修改状态
            cartItem.setChecked(checikStatus);
            //编码
            String s = JSON.toJSONString(cartItem);
            String encode = URLEncoder.encode(s, "utf-8");
            CookieUtil.addCookie(response,"192.168.16.172","/",cookie.getName(),encode,60*60*24*30,false);
        }
    }


    //将sku进行封装
    private CartItem sku2CartItem(Sku sku,Integer num) {
        Result<Spu> spuResult = spuFeign.findById(sku.getSpuId());
        Spu spu = spuResult.getData();
        CartItem cartItem = new CartItem();
        cartItem.setBrandName(sku.getBrandName());
        cartItem.setSpuId(sku.getSpuId());
        cartItem.setChecked(true);
        cartItem.setSkuId(sku.getId());
        cartItem.setName(sku.getName());
        cartItem.setPrice(sku.getPrice());
        cartItem.setNum(num);
        cartItem.setMoney(num*cartItem.getPrice()); //单价*数量
        cartItem.setPayMoney(num*cartItem.getPrice()); //实付金额
        cartItem.setImage(sku.getImage());
        cartItem.setWeight(sku.getWeight()*num); //重量=单个重量*数量
//分类ID设置
        cartItem.setCategoryId1(spu.getCategory1Id());
        cartItem.setCategoryId2(spu.getCategory2Id());
        cartItem.setCategoryId3(spu.getCategory3Id());
        return  cartItem;
    }
}


